﻿//上传图片后链接的时效性为永久
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Minio;
using Minio.DataModel;
using Minio.DataModel.Args;
using Newtonsoft.Json;

namespace Traceability.API.UploadImg.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class FileUploadController : ControllerBase
    {
        private readonly IMinioClient _minioClient;
        private readonly IConfiguration _configuration;
        private readonly string _bucketName;

        public FileUploadController(IMinioClient minioClient, IConfiguration configuration)
        {
            _minioClient = minioClient ?? throw new ArgumentNullException(nameof(minioClient));
            _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
            _bucketName = _configuration.GetSection("MinIO")["BucketName"] ?? "medical";
        }

        [HttpGet]
        public async Task<IActionResult> ListBuckets()
        {
            try
            {
                // ListBucketsAsync() 来获取 MinIO 服务器上的所有存储桶 (buckets
                // ConfigureAwait(false) 的作用是防止异步操作回到调用线程上继续执行，以避免死锁。
                var buckets = await _minioClient.ListBucketsAsync().ConfigureAwait(false);
                return Ok(buckets);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取存储桶列表失败: {ex.Message}");
                return StatusCode(500, $"获取存储桶列表失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 健康检查 - 验证MinIO连接
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> HealthCheck()
        {
            try
            {
                // 尝试列出存储桶来验证连接
                var buckets = await _minioClient.ListBucketsAsync().ConfigureAwait(false);
                
                // 检查目标存储桶是否存在
                var beArgs = new BucketExistsArgs().WithBucket(_bucketName);
                bool bucketExists = await _minioClient.BucketExistsAsync(beArgs);
                
                return Ok(new 
                {
                    Status = "Healthy",
                    MinIOConnected = true,
                    BucketName = _bucketName,
                    BucketExists = bucketExists,
                    TotalBuckets = buckets.Buckets.Count,
                    Timestamp = DateTime.UtcNow
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"健康检查失败: {ex.Message}");
                return StatusCode(503, new 
                {
                    Status = "Unhealthy",
                    MinIOConnected = false,
                    Error = ex.Message,
                    Timestamp = DateTime.UtcNow
                });
            }
        }

        /// <summary>
        /// 上传单个文件
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> UploadFile(IFormFile file)
        {
            try
            {
                // 验证文件
                if (file == null || file.Length == 0)
                {
                    return BadRequest("请选择一个有效的文件");
                }

                // 检查桶是否存在
                var beArgs = new BucketExistsArgs()
                    .WithBucket(_bucketName);
                bool found = await _minioClient.BucketExistsAsync(beArgs);

                // 如果桶不存在，则创建桶
                if (!found)
                {
                    var mbArgs = new MakeBucketArgs()
                        .WithBucket(_bucketName);
                    await _minioClient.MakeBucketAsync(mbArgs).ConfigureAwait(false);
                }
                
                // 生成3位随机数码
                Random random = new Random();
                string randomCode = random.Next(100, 999).ToString();

                // 获取文件名，加入全球唯一标识
                var objectName = $"{randomCode}_{file.FileName}";

                // 使用流数据上传文件 - 正确管理资源
                using (var stream = file.OpenReadStream())
                {
                    var putArgs = new PutObjectArgs()
                        .WithBucket(_bucketName)
                        .WithObject(objectName)
                        .WithStreamData(stream)
                        .WithContentType(file.ContentType)
                        .WithObjectSize(file.Length);
                    await _minioClient.PutObjectAsync(putArgs).ConfigureAwait(false);
                }

                // 直接拼接公开URL
                var url = $"http://{_configuration.GetSection("MinIO")["Endpoint"]}/{_bucketName}/{objectName}";
                return Ok(url);
            }
            catch (Exception ex)
            {
                // 记录详细错误信息
                Console.WriteLine($"文件上传失败: {ex.Message}");
                Console.WriteLine($"堆栈跟踪: {ex.StackTrace}");
                return StatusCode(500, $"文件上传失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 上传多个文件
        /// </summary>
        /// <param name="formFiles">要上传的文件集合</param>
        /// <returns>返回上传成功的文件名列表</returns>
        [HttpPost]
        public async Task<IActionResult> UploadFiles(IFormFileCollection formFiles)
        {
            try
            {
                // 验证文件集合
                if (formFiles == null || !formFiles.Any())
                {
                    return BadRequest("请至少选择一个文件");
                }

                // 检查存储桶是否存在
                var beArgs = new BucketExistsArgs()
                    .WithBucket(_bucketName);
                bool found = await _minioClient.BucketExistsAsync(beArgs);

                // 如果桶不存在则创建
                if (!found)
                {
                    var mbArgs = new MakeBucketArgs()
                        .WithBucket(_bucketName);
                    await _minioClient.MakeBucketAsync(mbArgs).ConfigureAwait(false);
                }

                var uploadedFileUrls = new List<string>();
                foreach (var formFile in formFiles)
                {
                    if (formFile == null || formFile.Length == 0)
                    {
                        continue; // 跳过无效文件
                    }

                    using var stream = formFile.OpenReadStream();

                    // 获取文件名，加入全球唯一标识
                    var objectName = $"{Guid.NewGuid()}_{formFile.FileName}";

                    // 上传文件到MinIO
                    var putArgs = new PutObjectArgs()
                        .WithBucket(_bucketName)
                        .WithObject(objectName)
                        .WithStreamData(stream)
                        .WithContentType(formFile.ContentType)
                        .WithObjectSize(stream.Length);

                    await _minioClient.PutObjectAsync(putArgs).ConfigureAwait(false);

                    // 直接拼接公开URL
                    var url = $"http://8.141.112.218:9000/{_bucketName}/{objectName}";
                    uploadedFileUrls.Add(url);
                }

                if (!uploadedFileUrls.Any())
                {
                    return BadRequest("没有成功上传任何文件");
                }

                // 以逗号分隔字符串返回
                var result = string.Join(",", uploadedFileUrls);
                return Ok(result);
            }
            catch (Exception ex)
            {
                // 记录详细错误信息
                Console.WriteLine($"批量文件上传失败: {ex.Message}");
                Console.WriteLine($"堆栈跟踪: {ex.StackTrace}");
                return StatusCode(500, $"批量文件上传失败: {ex.Message}");
            }
        }
    }
}